package com.qbb.server.constanct;

import java.io.File;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.converters.IntegerConverter;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.qbb.server.bean.services.QbbElementBean;
import com.qbb.server.bean.services.QbbRootBean;
import com.qbb.server.bean.services.QbbServiceBean;
import com.qbb.server.constanct.bean.QbbConfigBean;
import com.qbb.server.exception.NettyException;
import com.qbb.server.util.FileUtil;

/**
 * 类说明
 * 
 * @author chenhuaiao
 * @version V1.0 创建时间：Mar 17, 2015 5:56:55 PM
 */
public class QbbConfigUtil {
	private static QbbConfigUtil singleton = null;
	private static final String rootPath = QbbConfigUtil.class.getResource("/")
			.getPath();
	private List<Integer> portLists = new ArrayList<Integer>();
	private Map<String, QbbConfigBean> serviceMap = new Hashtable<String, QbbConfigBean>();

	public static void main(String[] args) {
		Object a = new IntegerConverter().convert(long.class, 1);
		System.out.println(a.getClass());
	}

	/**
	 * 通过服务名称获得服务对象的参数信息
	 * 
	 * @param name
	 * @return
	 */
	public static QbbConfigBean getMethod(String name) {
		return getSingleton().serviceMap.get(name);
	}

	public static List<Integer> getPorts() {
		return getSingleton().portLists;
	}

	private QbbConfigUtil() {
		initClientConfig();
	}

	private static QbbConfigUtil getSingleton() {
		if (singleton == null) {
			synchronized (QbbConfigUtil.class) {
				if (singleton == null) {
					singleton = new QbbConfigUtil();
				}
			}
		}
		return singleton;
	}

	private static QbbRootBean[] loadQbbConfig() {
		String dictionaryPath = rootPath + "qbb-server";
		List<File> files = FileUtil.getPathFileNames(dictionaryPath);
		if (files == null) {
			throw new NettyException("QbbClient cant load xml config file");
		}

		int fileSize = files.size();

		QbbRootBean[] allServerModels = new QbbRootBean[fileSize];

		// 创建saxReader对象
		SAXReader reader = new SAXReader();

		try {
			for (int i = 0; i < fileSize; i++) {

				List<QbbElementBean> elementsBeans = new ArrayList<QbbElementBean>();

				QbbRootBean rootBean = new QbbRootBean();
				rootBean.setBeans(elementsBeans);

				File file = files.get(i);
				Document document = reader.read(file);

				Element node = document.getRootElement();

				Element portElement = node.element("port");
				String portStr = portElement.getText().trim();
				int port = Integer.parseInt(portStr);

				rootBean.setPort(port);

				allServerModels[i] = rootBean;

				Iterator<Element> servicesElement = node.elementIterator();

				// 遍历
				while (servicesElement.hasNext()) {
					// 获取某个子节点对象
					Element service = servicesElement.next();
					// 对子节点进行遍历
					Attribute attr = service.attribute("beanName");
					if (attr == null) {
						continue;
					}
					String beanName = attr.getValue();

					List<QbbServiceBean> serviceList = new ArrayList<QbbServiceBean>();
					QbbElementBean elementBean = new QbbElementBean();
					elementBean.setBeanName(beanName.trim());
					elementBean.setServiceList(serviceList);

					elementsBeans.add(elementBean);

					Iterator<Element> serviceElement = service
							.elementIterator();
					while (serviceElement.hasNext()) {

						Element method = serviceElement.next();
						Attribute serviceAttr = method.attribute("name");
						if (serviceAttr == null) {
							continue;
						}
						String serviceName = serviceAttr.getValue().trim();
						String methodName = method.getText().trim();

						QbbServiceBean serviceBean = new QbbServiceBean();
						serviceBean.setServiceName(serviceName);
						serviceBean.setMethodName(methodName);

						serviceList.add(serviceBean);
					}

				}

			}
			return allServerModels;
		} catch (Exception e) {
			throw new NettyException(
					"QbbClient load xml config file have exception");
		}
	}

	private void initClientConfig() {
		QbbRootBean[] models = loadQbbConfig();
		if (models == null) {
			throw new NettyException("QbbClient cant load xml config file");
		}
		setServiceMap(models);
	}

	private void setServiceMap(QbbRootBean[] models) {
		int modelLen = models.length;

		Map<String, QbbConfigBean> cacheMap = new Hashtable<String, QbbConfigBean>();

		for (int i = 0; i < modelLen; i++) {
			QbbRootBean rootBean = models[i];

			int port = rootBean.getPort();
			if (!portLists.contains(port)) {
				portLists.add(port);
			}

			List<QbbElementBean> elementsList = rootBean.getBeans();
			if (elementsList.isEmpty()) {
				continue;
			}
			int elementsSize = elementsList.size();
			for (int j = 0; j < elementsSize; j++) {
				QbbElementBean element = elementsList.get(j);
				String beanName = element.getBeanName();

				List<QbbServiceBean> servicesList = element.getServiceList();
				if (servicesList.isEmpty()) {
					continue;
				}
				int servicesSize = servicesList.size();

				for (int k = 0; k < servicesSize; k++) {
					QbbServiceBean serviceBean = servicesList.get(k);

					String methodName = serviceBean.getMethodName();
					String serviceName = serviceBean.getServiceName();

					String chacheKey = serviceName + "_" + methodName;
					QbbConfigBean configBean = null;

					if (cacheMap.containsKey(chacheKey)) {
						configBean = cacheMap.get(chacheKey);
					} else {
						configBean = new QbbConfigBean();
						configBean.setBeanName(beanName);
						configBean.setMethodName(methodName);
						cacheMap.put(chacheKey, configBean);
					}

					serviceMap.put(serviceName, configBean);
				}
			}
		}
	}
}
